#include <retro.h>
#include "player.h"
#include "player.fpscounter.h"

#define FPS_SAMPLE_THRESHOLD  0.10
#define FPS_VALUE_THRESHOLD   0.01

using namespace Retro::Player::Graphic;

FPSCounter::FPSCounter()
{
  mSampleIndex  = 0;
  mSampleSum    = 0;
  mLastTime     = 0;
  mIgnored      = FALSE;
  mFPS          = 0;
  mInitialized  = FALSE;

  memset(mSamples, 0, sizeof(mSamples));
}

VOID FPSCounter::calcFPS()
{
  LARGE_INTEGER wTime;
  LARGE_INTEGER wFreq;

  QueryPerformanceCounter(&wTime);
  QueryPerformanceFrequency(&wFreq);

  if (mLastTime == 0)
    mLastTime = wTime.QuadPart;

  FPSREAL wDelta = (FPSREAL)(wTime.QuadPart - mLastTime) / wFreq.QuadPart;
  FPSREAL wLastSample = mSamples[(mSampleIndex - 1) % RETRO_FPS_SAMPLE_COUNT];

  mLastTime = wTime.QuadPart;

  if (fabs(wDelta - wLastSample) >
    wLastSample * FPS_SAMPLE_THRESHOLD &&
    !mIgnored)
  {
    mIgnored = TRUE;
    return;
  }

  mIgnored = FALSE;

  mSampleSum -= mSamples[mSampleIndex];
  mSampleSum += (mSamples[mSampleIndex] = wDelta);

  if (mSampleIndex == RETRO_FPS_SAMPLE_COUNT - 1)
    mInitialized = TRUE;

  mSampleIndex = (mSampleIndex + 1) % RETRO_FPS_SAMPLE_COUNT;

  FPSREAL wCalcFPS = 1 / (mSampleSum / RETRO_FPS_SAMPLE_COUNT);
  FPSREAL wMaxDiff = min(5.0, mFPS * FPS_VALUE_THRESHOLD);

  if (mInitialized && fabs(mFPS - wCalcFPS) > wMaxDiff)
    mFPS = wCalcFPS;
}

VOID FPSCounter::init(Display::DisplayDevice* iDevice)
{
}

VOID FPSCounter::uninit(Display::DisplayDevice* iDevice)
{
}
